<template>
  <el-dialog
    v-model="visible"
    :title="title"
    :width="width"
    append-to-body
    :close-on-press-escape="false"
    :close-on-click-modal="false"
    custom-class="add-update-dialog"
  >
    <form-create
      v-model="value"
      :disabled="isDetail"
      v-model:api="fApi"
      :rule="rule"
      :option="option"
    />
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="submit">确定</el-button>
        <el-button @click="cancel">取消</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
  import { ref, computed, watch, nextTick } from 'vue';
  import { getXzqh } from '@/api/common';
  import { getInfo } from '@/api/login';

  const props = defineProps({
    modelValue: {
      type: Boolean,
      default: false,
    },
    form: {
      type: Object,
      default: () => ({}),
    },
    isDetail: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: '',
    },
    width: {
      type: String,
      default: '800px',
    },
    submitForm: {
      type: Function,
      default: () => {},
    },
    cancel: {
      type: Function,
      default: () => {},
    },
    field: {
      type: Array,
      default: () => [],
    },
  });
  const emits = defineEmits(['update:modelValue', 'update:form']);

  const fApi = ref(null);
  const option = ref({
    submitBtn: false,
    form: {
      inline: false,
      'label-width': '80px',
    },
  });
  const hasOnEvent = ref(false);
  const userInfo = ref({});

  const visible = computed({
    set(val) {
      emits('update:modelValue', val);
    },
    get() {
      return props.modelValue;
    },
  });

  const value = computed({
    get() {
      const item = props.form;
      const ans = Object.keys(item).reduce((prev, curr) => {
        let val = item[curr];
        const controlType = getControlType(curr);
        if (controlType === 'checkbox' && !Array.isArray(val)) {
          val = (val || null)?.split(',') ?? [];
        }
        prev[curr] = val;
        return prev;
      }, {});
      return ans;
    },
    set(item) {
      const ans = Object.keys(item).reduce((prev, curr) => {
        const val = item[curr];
        prev[curr] = Array.isArray(val) ? val.join(',') : val;
        return prev;
      }, {});
      emits('update:form', ans);
    },
  });
  const rule = computed(() => props.field);

  const primaryField = computed(() => {
    return rule.value.filter((k) => k.ext.primary)?.[0]?.field ?? '';
  });

  function getControlType(colName) {
    return rule.value.filter((k) => k.ext.colName === colName)?.[0]?.ext.controlType ?? '';
  }

  // 控制新增修改的状态
  watch(value, (v) => {
    const isAdd = primaryField.value ? !v[primaryField.value] : false;
    const isUpdate = primaryField.value ? !!v[primaryField.value] : false;

    if (isAdd) {
      props.field.forEach((item) => {
        const { insertStatus, primary, autoFillExpWeb } = item.ext;

        if (primary) {
          return;
        }

        if (autoFillExpWeb) {
          let fillValue = '';
          if (autoFillExpWeb === 'Date') {
            fillValue = new Date();
          } else if (autoFillExpWeb.startsWith('userInfo')) {
            const k = autoFillExpWeb.split('.')[1];
            fillValue = userInfo.value[k];
          }
          fApi.value?.setValue({
            [item.field]: fillValue,
          });
        }

        if (insertStatus?.includes('隐藏')) {
          fApi.value?.mergeRule(item.field, {
            hidden: true,
          });
        } else if (insertStatus?.includes('只读')) {
          fApi.value?.mergeRule(item.field, {
            props: {
              readonly: true,
              disabled: true,
            },
          });
        } else {
          fApi.value?.mergeRule(item.field, {
            hidden: false,
            props: {
              readonly: false,
              disabled: false,
            },
          });
        }
      });
    }

    if (isUpdate) {
      props.field.forEach((item) => {
        const { updateStatus, primary, autoFillExpWeb, onlyInsert } = item.ext;

        if (primary) {
          return;
        }

        if (autoFillExpWeb && !onlyInsert) {
          let fillValue = '';
          if (autoFillExpWeb === 'Date') {
            fillValue = new Date();
          } else if (autoFillExpWeb.startsWith('userInfo')) {
            const k = autoFillExpWeb.split('.')[1];
            fillValue = userInfo.value[k];
          }
          fApi.value?.setValue({
            [item.field]: fillValue,
          });
        }

        if (updateStatus?.includes('隐藏')) {
          fApi.value?.mergeRule(item.field, {
            hidden: true,
          });
        } else if (updateStatus?.includes('只读')) {
          fApi.value?.mergeRule(item.field, {
            props: {
              readonly: true,
              disabled: true,
            },
          });
        } else {
          fApi.value?.mergeRule(item.field, {
            hidden: false,
            props: {
              readonly: false,
              disabled: false,
            },
          });
        }
      });
    }
  });

  function getXzqhlx(name) {
    return rule.value.filter((k) => k.ext.colName === name)?.[0]?.ext?.xzqhlx ?? '';
  }

  function updateXzqh() {
    for (const item of props.field) {
      const { relationDictType, xzqhlx, parentXzqhField, colName } = item.ext;
      if (relationDictType === '行政区划') {
        const emitPrefix = colName.replace('_', '').toLowerCase();
        fApi.value?.on(`${emitPrefix}-focus`, (e) => {
          e?.stopPropagation();
          const parentXzqhlx = getXzqhlx(parentXzqhField);
          const params = {
            ancestorId: parentXzqhlx ? fApi.value?.getValue(parentXzqhField) ?? '' : '',
            xzqhlx,
          };
          getXzqh(params).then(({ data }) => {
            fApi.value?.mergeRule(colName, {
              options: data,
            });
          });
        });
      }
    }
  }

  function submit() {
    fApi.value?.validate((valid) => {
      if (valid === true) {
        props.submitForm();
      }
    });
  }

  watch(visible, () => {
    nextTick(() => {
      if (!hasOnEvent.value) {
        updateXzqh();
        hasOnEvent.value = true;
      }
    });
  });

  function initUserInfo() {
    getInfo().then(({ user }) => {
      userInfo.value = {
        userId: user.userId,
        username: user.userName,
        userXzqhQu: user.dept.xzqhHierarchy.district,
        userXzqhXq: user.dept.xzqhHierarchy.xq,
        userXzqhSq: user.dept.xzqhHierarchy.community,
        userXzqhWg: user.dept.xzqhHierarchy.wg,
        userXzqhJd: user.dept.xzqhHierarchy.street,
        userPhone: user.phonenumber,
        userNickName: user.nickName,
        userIdno: user.idno,
        deptId: user.deptId,
        deptName: user.dept.deptName,
      };
    });
  }

  initUserInfo();
</script>

<style lang="scss">
  .add-update-dialog {
    .el-select--default {
      width: 100%;
    }
  }
</style>
